﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using KZ400B.AxleSettings;
using System.Threading;

namespace KZ400B.Controls
{
    //public delegate void StateChange(AxleAction action,string state);
    //public delegate void OneStepStateChange(string aName,bool bRun);
    /// <summary>
    /// nAxleState.xaml 的交互逻辑
    /// </summary>
    public partial class nAxleState : UserControl
    {
        MouseButtonEventHandler m_btnOSA_DH = null;
        MouseButtonEventHandler m_btnOSA_UH = null;
        public nAxleState()
        {
            InitializeComponent();
            
            this.Loaded += new RoutedEventHandler(AxleState_Loaded);
            this.Unloaded += new RoutedEventHandler(AxleState_Unloaded);
            AxleManager.OnAxleActionResponse += new AxleActionResponse(AxleManager_OnAxleActionResponse);
            m_btnOSA_DH = new MouseButtonEventHandler(btnOneStepAddtion_MouseLeftButtonDown);
            m_btnOSA_UH = new MouseButtonEventHandler(btnOneStepAddtion_MouseLeftButtonUp);
            btnOneStepAddtion.AddHandler(Button.MouseLeftButtonDownEvent, m_btnOSA_DH, true);
            btnOneStepAddtion.AddHandler(Button.MouseLeftButtonUpEvent, m_btnOSA_UH, true);
        }

        void AxleState_Unloaded(object sender, RoutedEventArgs e)
        {
            btnOneStepAddtion.RemoveHandler(Button.MouseLeftButtonDownEvent, m_btnOSA_DH);
            btnOneStepAddtion.RemoveHandler(Button.MouseLeftButtonUpEvent, m_btnOSA_UH);
            AxleManager.OnAxleActionResponse -= new AxleActionResponse(AxleManager_OnAxleActionResponse);

        }

        void AxleManager_OnAxleActionResponse(string axleName
            , Axle axle
            , AxleActions action
            , bool success
            , string message)
        {
            if (action == AxleActions.ContactRespond && success)
            {
                AxleManager.QueryPosition(AxleName);
                int aLevel = 0;
                if (cmbAcceleration.SelectedValue != null && int.TryParse(cmbAcceleration.SelectedValue.ToString(), out aLevel))
                {
                    if (aLevel != Axle.AccelerationLevel.Constant)
                    {
                        Axle.AccelerationLevel acc = new Axle.AccelerationLevel(aLevel);
                        if (AxleManager.AccelerationSetting(m_axleName, acc))
                        {
                            setState(
                            string.Format("加速度({0}|[{1}])设置成功"
                                , m_axleName, acc.ToString()
                                )
                            );
                        }
                        else
                        {
                            setState(
                            string.Format("加速度({0}|[{1}])设置失败"
                                , m_axleName, acc.ToString()
                                )
                            );
                        }
                    }
                }
            }
            else if (action == AxleActions.ToZeroFinish && success )
            {
                if (axleName.Equals(AxleCacheManager.AxleList[m_axleName].Name) || axleName.Equals(Axle.AllAxleName))
                {
                    OnToZeroSucceed();
                }
            }
            /*
            else if (action == AxleActions.ToZero
                || action == AxleActions.Stop
                || action == AxleActions.Run
                )
            {
                if (axleName.Equals(AxleName) 
                    || AxleName.Equals(Axle.AllAxleName)
                    )
                {
                    AxleManager.QueryPosition(AxleName);
                }

            }
             */
        }

        public event StateChange OnStateChanged;
        public event OneStepStateChange OnOneStepStateChange;

        string m_axleName = string.Empty;
        void AxleState_Loaded(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(AxleName))
            {
                throw new Exception("AxleName 不能为空");
            }
            //m_Axle = AxleCacheManager.getAxle(AxleName);
            
            //grpAxle.Header = string.Format("{0}轴",AxleName);
            try
            {
                grpAxle.Content = string.Format("{0}轴", AxleName);
                m_axleName = AxleName;
                if (AxleCacheManager.AxleList[AxleName] == null)
                    return;
                //AxlePosition = (double)( m_Axle.Position );
                m_orgPosition = AxleCacheManager.AxleList[AxleName].Position;
                m_lastPosition = AxleCacheManager.AxleList[AxleName].Position;
                m_lastUnit = AxleCacheManager.AxleList[AxleName].RunningUnit;



                labAxlePostion.Content = AxleCacheManager.AxleList[AxleName].Position.ToString(MySetting.PositionDisDeciFormatter);

                m_btnHitRec = new Dictionary<Button, DateTime>();
                m_isolk = new object();

                #region bind
                addtionDirectBind(
                    AxleCacheManager.AxleList[AxleName].OnestepAddtion >= 0
                    ? Axle.Direction.ForwardDirection.Value
                    : Axle.Direction.BackDirection.Value
                    );
                addtionBind(Math.Abs(AxleCacheManager.AxleList[AxleName].OnestepAddtion));
                targetBind(AxleCacheManager.AxleList[AxleName].RunTarget);
                accelerationBind(AxleCacheManager.AxleList[AxleName].RunAcceleration);
                tozeroSpeedBind();

                AxlePositionUnit = (int)AxleCacheManager.AxleList[AxleName].RunningUnit;
                #endregion
                //if (m_Axle.OnestepAddtion == 0)
                //{
                //    cmbAddtionDirect.SelectedValue = (int)Axle.Direction.ForwardDirection.Value;
                //    cmbAddtion.SelectedValue = m_Axle.OnestepAddtion;
                //}
                //else
                //{
                //    cmbAddtionDirect.SelectedValue = (int)Axle.Direction.BackDirection.Value;
                //    cmbAddtion.SelectedValue = 0 - m_Axle.OnestepAddtion;
                //}
                txtSpeed.Text = AxleCacheManager.AxleList[AxleName].RunSpeed.ToString();
                txtTozeroSpeed.Text = AxleCacheManager.AxleList[AxleName].TozeroSpeed.ToString();
                changeParam();

                setState(string.Format("加载完成"));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                setState(string.Format("加载异常:{0}",ex.Message));
            }
            


        }

        public static DependencyProperty AxleNameProperty = DependencyProperty.Register(
        "AxleName", typeof(string)
        , typeof(nAxleState)
        , new PropertyMetadata(string.Empty)
    );

        public void RefreshDisplay()
        {
            labAxlePostion.Content = m_lastPosition.ToString(MySetting.PositionDisDeciFormatter);
        }

        public string AxleName
        {
            get { return (string)GetValue(AxleNameProperty); }
            set { SetValue(AxleNameProperty, value); }
        }

        //private Axle m_Axle;
        //private RunningUnit m_rUnit;

        /// <summary>
        /// 相对零位设置
        /// </summary>
        public static DependencyProperty AxleRelativeZeroProperty = DependencyProperty.Register(
            "AxleRelativeZero", typeof(double)
            , typeof(nAxleState)
             , new PropertyMetadata((double)0.0F, new PropertyChangedCallback(OnAxleRelativeZeroChange))
            );

        public double AxleRelativeZero
        {
            get { return (double)GetValue(AxleRelativeZeroProperty); }
            set { SetValue(AxleRelativeZeroProperty, value); }
        }

        private static void OnAxleRelativeZeroChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            nAxleState control = (nAxleState)d;
            //if ((int)(control.AxlePosition) == 0)
            //{ control.labAxlePostion.Content = "0.000"; }
            //else
            //{ control.labAxlePostion.Content = control.AxlePosition.ToString("0.000"); }
            AxleCacheManager.AxleList[control.AxleName].RelativeZero = control.AxleRelativeZero;
            AxleCacheManager.Update(AxleCacheManager.AxleList[control.AxleName]);
        }

        
        public static DependencyProperty AxlePositionProperty = DependencyProperty.Register(
            "AxlePosition",typeof(double)
            , typeof(nAxleState)
             , new PropertyMetadata(Axle.DefaultPosition, new PropertyChangedCallback(OnPositionChange))
            );

        public double AxlePosition
        {
            get { return (double)GetValue(AxlePositionProperty); }
            set { SetValue(AxlePositionProperty, value); }
        }

        private static void OnPositionChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            nAxleState control = (nAxleState)d;
            //if ((int)(control.AxlePosition) == 0)
            //{ control.labAxlePostion.Content = "0.000"; }
            //else

            //if (AxleCacheManager.AxleList[control.AxleName] != null)
            //{
               // AxleCacheManager.AxleList[control.AxleName].Position = AxleCacheManager.getAxle(control.AxleName).Position;
                //double pos = Axle.ComputeRelativePosition(control.AxlePosition, AxleCacheManager.AxleList[control.AxleName].RelativeZero);
                double pos = control.AxlePosition;
                //double pos = control.computeRelativePosition(control.AxlePosition);
                //if (control.m_lastUnit == RunningUnits.Step)
                //{
                //    pos = pos / control.m_Axle.OnestepDisplacement;
                //}
                control.labAxlePostion.Content = pos.ToString(MySetting.PositionDisDeciFormatter);
                //{ control.labAxlePostion.Content = pos.ToString(MySetting.PositionDisDeciFormatter); }
                //AxleCacheManager.AxleList[control.AxleName].Position = pos;
                control.m_orgPosition = pos;
                control.m_lastPosition = pos;
                control.m_orgUnit = (RunningUnits)control.AxlePositionUnit;

                 control.setBtnState_AxleNotRunning();
                //AxleCacheManager.Update(control.m_Axle);
            //}
        }

        bool m_isNeedChangeToStep = false;
        bool m_isNeedChangeToOtherUnit = false;
        double m_orgPosition = 0.0F;
        double m_lastPosition = 0.0F;
        RunningUnits m_orgUnit = RunningUnits.UnDefined;
        RunningUnits m_lastUnit = RunningUnits.UnDefined;

        //private double computeRelativePosition(double position)
        //{
        //    double ps = position;
        //    if (position >= 0)
        //    {
        //        if (m_Axle.RelativeZero > 0)
        //        {
        //            ps = position - m_Axle.RelativeZero;
        //        }
        //        else
        //        {
        //            ps = position + m_Axle.RelativeZero;
        //        }
        //    }
        //    else
        //    {
        //        if (m_Axle.RelativeZero > 0)
        //        {
        //            ps = position + m_Axle.RelativeZero;
        //        }
        //        else
        //        {
        //            ps = position - m_Axle.RelativeZero;
        //        }
        //    }
        //    return ps;
        //}

        /*
         //单位转换，显示要跟着相应转换
         */
        //private double convertPositionByUnit(double position)
        //{
        //    double ps = position;
        //    if (m_orgUnit == RunningUnits.Step)
        //    {
        //        if (m_isNeedChangeToOtherUnit)
        //        {
        //            ps = position * m_Axle.OnestepDisplacement;
        //        }
        //    }
        //    else { 
        //        if (m_isNeedChangeToStep)
        //        {
        //            int ips = Convert.ToInt32(position / m_Axle.OnestepDisplacement);
        //            ps = (double)ips;
        //        }
        //    }
        //    return ps;
        //}

        public static DependencyProperty AxlePositionUnitProperty = DependencyProperty.Register(
        "AxlePositionUnit", typeof(int)
        , typeof(nAxleState)
         , new PropertyMetadata((int)RunningUnits.UnDefined, new PropertyChangedCallback(OnAxlePositionUnitChange))
        );

        public int AxlePositionUnit
        {
            get { return (int)GetValue(AxlePositionUnitProperty); }
            set { SetValue(AxlePositionUnitProperty, value); }
        }

        private static Dictionary<string, string> sdictUnits = new Dictionary<string, string>() 
        { 
            {"步数","step"},
            {"毫米","mm"},
            {"度数","deg"},
            {"STEP","step"},
            {"MILLIMETER","mm"},
            {"RADIAN","deg"},
            {"MM","mm"}
        };

       private static string getUnitNameByAltName(string unitAltName)
        {
            if (string.IsNullOrEmpty(unitAltName))
            {
                return string.Empty;
            }
            if (sdictUnits.ContainsKey(unitAltName))
            { 
                return sdictUnits[unitAltName];
            }
            else if (sdictUnits.ContainsKey(unitAltName.ToUpper()))
            {
                return sdictUnits[unitAltName.ToUpper()];
            }
            return string.Empty;
        }

        private static void OnAxlePositionUnitChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            nAxleState control = (nAxleState)d;

            if (AxleCacheManager.AxleList[control.AxleName] != null)
            {
                PositionCacheManager.ChangePosition(control.AxleName, AxleCacheManager.AxleList[control.AxleName].DisplayPosition, true);
            }

            int intPu = control.AxlePositionUnit;
            RunningUnits pu = (RunningUnits)intPu;
            
            string name = RunningUnitCacheManager.getName(intPu);
            string altName = RunningUnitCacheManager.getAltName(intPu);
            string uName = getUnitNameByAltName(altName);

            control.labAxlePostionUnit.Content = altName;
            control.labAddtionUnit.Content = altName;
            control.labTargetUnit.Content = altName;

            control.labSpeedUnit.Content = uName;
            control.labTozeroSpeedUnit.Content = uName;

            

            //if (control.m_lastUnit == RunningUnits.UnDefined)
            //{
            //    control.m_isNeedChangeToOtherUnit = false;
            //    control.m_isNeedChangeToStep = false;
            //}
            //else if (
            //    control.m_lastUnit == RunningUnits.Step
            //    && control.m_lastUnit != pu
            //    )//从步数转换为其它单位
            //{
            //    control.m_isNeedChangeToOtherUnit = true;
            //    control.m_isNeedChangeToStep = false;
            //}
            //else if(
            //    control.m_lastUnit != RunningUnits.Step 
            //    && pu == (int)RunningUnits.Step
            //    )//从其它单位转换为步数
            //{
            //    control.m_isNeedChangeToOtherUnit = false;
            //    control.m_isNeedChangeToStep = true;
            //}
            //control.m_lastUnit = (RunningUnits)control.AxlePositionUnit;

            ////转换显示位置
            //if (control.m_Axle != null)
            //{
            //    double npos = control.convertPositionByUnit(control.m_orgPosition);
            //    { control.labAxlePostion.Content = npos.ToString(MySetting.PositionDisDeciFormatter); }
                    
            //        control.m_Axle.Position = npos;
            //        control.m_Axle.RunningUnit = pu;
            //        AxleCacheManager.Update(control.m_Axle);

            //    control.m_lastPosition = npos;
            //}
            //else {
            //    control.m_lastUnit = RunningUnits.UnDefined;
            //}
        }

        //private double computeAddtion(double target,ref int dir)
        //{
        //    double nt = target;
        //    dir = Axle.Direction.ForwardDirection.Value;
        //    double rZero = m_Axle.RelativeZero;
        //    if (m_lastUnit == RunningUnits.Step)
        //    {
        //        rZero = rZero / m_Axle.OnestepDisplacement;
        //    }
        //    if ((nt + rZero ) < 0)
        //    {
        //        //if (nt > (m_Axle.Position + m_Axle.RelativeZero))
        //        {
        //            throw new Exception("运行目标超越绝对零位!");
        //        }
        //    }

        //    if (nt < m_Axle.Position)
        //    {
        //        if (nt < 0)
        //        {
        //            nt = 0 - target;
        //            //if (m_Axle.RelativeZero > 0)
        //            //{
        //            //    nt += m_Axle.RelativeZero;
        //            //}
        //            nt += m_Axle.Position;// +m_Axle.RelativeZero;
                    
        //        }
        //        else
        //        {
        //            nt -= m_Axle.Position;
        //        }
        //        if (nt < 0)
        //        {
        //            nt = 0 - nt;
        //        }
        //        dir = Axle.Direction.BackDirection.Value;
        //    }
        //    else
        //    {
        //        if (m_Axle.RelativeZero < 0)
        //        {
        //            throw new Exception("绝对零位不能小于0!");
        //            nt -= rZero;
        //        }
        //        nt -= m_Axle.Position;// +m_Axle.RelativeZero;
        //    }
        //    return nt;
        //}

        Button getButtonBySender(object sender)
        {
            try
            {
                if (sender != null && sender is Button)
                {
                    return sender as Button;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return null;
        }

        void btnDisabled(object sender)
        { 
            try
            {
                Button btn = getButtonBySender(sender);
                if (btn != null)
                {
                    btn.IsEnabled = false;
                    WpfEvent.DoEvents();
                    //btn.IsEnabledChanged += new DependencyPropertyChangedEventHandler(btn_IsEnabledChanged);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        void btn_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            
        }
        void btnDelayEnable(object sender) { btnDelayEnable(sender, null); }
        //void btnDelayEnable(object sender,AxleActionManage actionManager)
        void btnDelayEnable(object sender, object actionManager)    
        {
            Button btn = getButtonBySender(sender);
            if (btn != null)
            {
                btn.IsEnabled = true;
                //btn.Dispatcher.BeginInvoke(new Action( delegate() {

                //    int timeout = 1000;
                //    if (actionManager != null)
                //    {
                        
                //        while(actionManager.IsActionReady(AxleName ) && timeout > 0 )
                //        {
                //            Thread.Sleep(200);
                //            timeout -= 200;
                //        }
                //        actionManager.UnRegist();
                //    }
                //    else
                //    {
                //        while ( timeout > 0)
                //        {
                //            Thread.Sleep(200);
                //            timeout -= 200;
                //        }
                //    }
                //    btn.IsEnabled = true;
                //}
                //));
                
            }
        }

        Dictionary<Button, DateTime> m_btnHitRec = null;
        bool canResponse(object sender)
        {
            Button btn = getButtonBySender(sender);
            return canResponse(btn);
        }
        bool canResponse(Button btn)
        {
            if(btn == null) return false;
            DateTime nT = DateTime.Now;
            if (m_btnHitRec == null) return true;
            if (m_btnHitRec.Count == 0 || !m_btnHitRec.ContainsKey(btn))
            {
                m_btnHitRec.Add(btn, nT);
                return true;
            }
            TimeSpan ts = nT - m_btnHitRec[btn];
            m_btnHitRec[btn] = nT;
            if (ts.TotalMilliseconds > 500)
            {
                return true;    
            }
            return false;
        }

        public void setBtnState_AxleRunning()
        {
            Dispatcher.BeginInvoke(new Action(delegate()
            {
                btnTozero.IsEnabled = false;
                btnRun.IsEnabled = false;
                btnOneStepAddtion.IsEnabled = false;
                btnSetRelativelyZero.IsEnabled = false;
            }));
        }

        public void setBtnState_AxleNotRunning()
        {
            Dispatcher.BeginInvoke(new Action(delegate()
            {
                btnTozero.IsEnabled = true;
                btnRun.IsEnabled = true;
                btnOneStepAddtion.IsEnabled = true;
                btnSetRelativelyZero.IsEnabled = true;
            }));
        }
        bool cx_check()
        {
            if (!AxleManager.IsOpen)
            {
                setState("未连接,请检查连接状态!");
                return false;
            }
            return true;
        }
        private void btnRun_Click(object sender, RoutedEventArgs e)
        {
            if (!cx_check()) return;
            if (!canResponse(sender)) return;
            btnDisabled(sender);
            bool bRst = false;
            //AxleActions action = AxleActions.RunFinish;
            //AxleActionManage actionM = new AxleActionManage();
            //actionM.Regist(AxleName,action);
            int direct = Axle.Direction.ForwardDirection.Value;
            double totalStep = 0;
            try
            {
                if (!double.TryParse(cmbTarget.SelectedItem.ToString(), out totalStep))
                {
                    return;
                }
                Axle tAxle = AxleCacheManager.AxleList[AxleName];
                //if (double.TryParse(cmbTarget.SelectedItem.ToString(), out totalStep))
                //{
                    totalStep = AxleCacheManager.AxleList[AxleName].ComputeAddtion(totalStep, ref direct);
                    if (totalStep == 0.0F)
                    {
                        return;
                    }
                    //if (totalStep < 0)
                    //{
                    //    direct = Axle.Direction.BackDirection.Value;
                    //    totalStep = 0 - totalStep;
                    //}
                    AxleCacheManager.AxleList[AxleName].Addtion = totalStep;

                    Axle.Direction dirt = new Axle.Direction(direct);
                    double pwm = AxleCacheManager.AxleList[AxleName].getRunPwm(m_runSpeed);

                    bool setRst = AxleManager.ParameterSetting(AxleName
                        , dirt
                        , pwm
                        , AxleCacheManager.AxleList[AxleName].TotalStep);
                    if (setRst)
                    {
                        setState(
                        string.Format("参数设置({0}|[{1}]|{2}|{3})成功"
                            , AxleName, dirt.ToString()
                            , pwm
                            , AxleCacheManager.AxleList[AxleName].TotalStep
                            )
                        );
                        AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                        bRst = AxleManager.Run(AxleName);
                    }
                    else
                    {
                        setState(
                            string.Format("参数设置({0}|[{1}]|{2}|{3})失败"
                                , AxleName, dirt.ToString()
                                , pwm
                                , AxleCacheManager.AxleList[AxleName].TotalStep
                                )
                            );
                    }
                //}//if double try parse
            }
            catch (Exception ex)
            {
                setState(
                                string.Format("参数设置错误:({0})"
                                    , ex.Message
                                    )
                                );
            }
            finally {
                if (bRst)
                {
                    setBtnState_AxleRunning();
                }
                btnDelayEnable(sender); 
            }
            
        }

        /// <summary>
        /// 设置相对零位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSetRelativelyZero_Click(object sender, RoutedEventArgs e)
        {
            if (!cx_check()) return;
            if (!canResponse(sender)) return;
            btnDisabled(sender);
            
            bool rst = AxleManager.RelativeZero(AxleName);
            setState(
            string.Format("相对零位设置({0}|[{1}])"
                , AxleName
                , rst ? "成功" : "失败"
                )
            );
            if (rst)
            {
                try
                {
                    ParameterCacheManager.Update(AxleName, Axle.Direction.ForwardDirection, double.MinValue, double.MinValue);
                    int ra = AxleCacheManager.AxleList[AxleName].RunAcceleration;
                    if (ra != Axle.AccelerationLevel.Constant && ra != Axle.AccelerationLevel.Empty)
                    {
                        AxleManager.AccelerationSetting(AxleName, new Axle.AccelerationLevel(ra));
                    }
                    //m_Axle.RelativeZero = m_Axle.Position;
                    //AxleCacheManager.Update(m_Axle);

                    //double pos = 0.0F;
                    //double nPos = 0.0F;
                    //rst = AxleManager.QueryOneAxlePosition(AxleName, ref pos);
                    //if (rst)
                    //{
                    //    AxleCacheManager.AxleList[AxleName].RelativeZero = pos;
                    //    nPos = Axle.ComputeRelativePosition(pos, pos);
                    //    //AxleCacheManager.AxleList[AxleName].Position = nPos;
                    //    AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                    //    labAxlePostion.Dispatcher.BeginInvoke(new Action(delegate()
                    //        {
                    //            //labAxlePostion.Content = "0.000"; 
                    //            //AxlePosition = 0.0F;
                    //            //AxlePosition = pos;
                    //            PositionCacheManager.ChangePosition(AxleName, AxleCacheManager.AxleList[AxleName].DisplayPosition, true);
                    //            //labAxlePostion.Content = 0.ToString(MySetting.PositionDisDeciFormatter);
                    //        }));

                    //}
                }
                catch (Exception ex)
                {
                    setState(
                                    string.Format("参数设置错误:({0})"
                                        , ex.Message
                                        )
                                    );
                }
                finally { if (rst) { btnDelayEnable(sender); } }
            }
            /*
            double oldZero = m_Axle.RelativeZero;
            double newZero = 0;
            double addtion = 0;
            if (cmbTarget.SelectedItem != null && double.TryParse(cmbTarget.SelectedItem.ToString(), out newZero))
            {
                Axle.Direction dirt = Axle.Direction.ForwardDirection;
                if (newZero > oldZero)
                {
                    addtion = newZero - oldZero;
                }
                if (newZero < oldZero)
                {
                    dirt = Axle.Direction.BackDirection;
                    addtion = oldZero - newZero;
                }
                if (addtion > 0)
                {
                    m_Axle.RelativeZero = newZero;
                    
                    m_Axle.Addtion = (int)addtion;
                    double pwm = m_Axle.getRunPwm(m_runSpeed);
                    bool rst = AxleManager.ParameterSetting(
                        AxleName
                        , dirt
                        , pwm
                        , m_Axle.TotalStep);

                    setState(
                        string.Format("参数设置({0}|[{1}]|{2}|{3}){4}"
                            , AxleName, dirt.ToString()
                            , pwm
                            , m_Axle.TotalStep
                            ,rst ? "成功" : "失败"
                            )
                        );

                    if (rst)
                    {
                        AxleCacheManager.Update(m_Axle);
                        rst = AxleManager.RelativeZero(AxleName);
                        setState(
                        string.Format("相对零位设置({0}|[{1}])"
                            , AxleName
                            , rst ? "成功" : "失败"
                            )
                        );
                        if (rst)
                        {
                            AxleManager.QueryPosition(AxleName);
                        }
                    }
                }
            }*/
            
        }

        /// <summary>
        /// 归零
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTozero_Click(object sender, RoutedEventArgs e)
        {
            if (!cx_check()) return;
            if (!canResponse(sender)) return;
            btnDisabled(sender);
            bool bRst = false;
            //AxleActions action = AxleActions.ToZeroFinish;
            //AxleActionManage actionM = new AxleActionManage();
            //actionM.Regist(AxleName, action);
            try
            {
                bRst = AxleManager.ToZero(AxleName, AxleCacheManager.AxleList[AxleName].getTozeroPwm(m_tozeroSpeed));
                //AxleManager.setParameterChanged(AxleName, true);
            }
            catch (Exception ex)
            {
                setState(
                                string.Format("参数设置错误:({0})"
                                    , ex.Message
                                    )
                                );
            }
            finally {
                if (bRst)
                {
                    setBtnState_AxleRunning();
                }
                btnDelayEnable(sender); 
            }
        }

        /// <summary>
        /// 归零成功后需要调用
        /// </summary>
        public void OnToZeroSucceed()
        {
            AxleCacheManager.AxleList[m_axleName].RelativeZero = 0;
            AxleCacheManager.AxleList[m_axleName].Position = 0;
            labAxlePostion.Dispatcher.BeginInvoke(new Action(delegate()
            { 
                //labAxlePostion.Content = "0.000"; 
                //AxlePosition = 0;
                PositionCacheManager.ChangePosition(m_axleName, 0, true);
                labAxlePostion.Content = 0.ToString(MySetting.PositionDisDeciFormatter);
            }));
            AxleCacheManager.Update(AxleCacheManager.AxleList[m_axleName]);
        }


        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            if (!cx_check()) return;
            if (!canResponse(sender)) return;
            btnDisabled(sender);
            bool bRst = false;
            //AxleActions action = AxleActions.StopFinish;
            //AxleActionManage actionM = new AxleActionManage();
            //actionM.Regist(AxleName, action);
            try
            {
                bRst = AxleManager.Stop(AxleName);
            }
            catch (Exception ex)
            {
                setState(
                                string.Format("参数设置错误:({0})"
                                    , ex.Message
                                    )
                                );
            }
            finally {
                if (bRst)
                {
                    setBtnState_AxleNotRunning();
                }
                btnDelayEnable(sender);
            }
        }

        //private void btnDown_Click(object sender, RoutedEventArgs e)
        //{

        //}

        //private void btnUp_Click(object sender, RoutedEventArgs e)
        //{

        //}
        double m_osTotalStep = 0;
        double m_osRunSpeed = 0.0F;
        public void AddOneStepAddtion()
        {
            if (!IsOneStepRunning) return;
            int direct = 0;
            double totalStep = m_osTotalStep;
            double runSpeed = m_osRunSpeed;
            try
            {
                

                direct = m_isForward
                    ? (int)Axle.Direction.ForwardDirection.Value
                    : (int)Axle.Direction.BackDirection.Value;

                double rTS = m_isForward ? totalStep : 0 - totalStep;

                OneStepAddtionState os = new OneStepAddtionState(m_axleName, rTS , runSpeed, this);
                OneStepAddManager.addOneState(os);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        
        void doOneStepAddtion1()
        {
            if (!canResponse(btnOneStepAddtion)) return;
            btnDisabled(btnOneStepAddtion);
            bool bRst = false;
            //AxleActions action = AxleActions.RunFinish;
            //AxleActionManage actionM = new AxleActionManage();
            //actionM.Regist(AxleName, action);
            int direct = 0;
            int totalStep = 0;
            try
            {
                if (!int.TryParse(cmbAddtion.SelectedItem.ToString(), out totalStep))
                {
                    return;
                }

                direct = m_isForward
                    ? (int)Axle.Direction.ForwardDirection.Value
                    : (int)Axle.Direction.BackDirection.Value;

                //if (int.TryParse(cmbAddtion.SelectedItem.ToString(), out totalStep))
                //{
                double rTS = m_isForward ? totalStep : 0 - totalStep;
                if (AxleCacheManager.AxleList[AxleName].DisplayPosition
                    + AxleCacheManager.AxleList[AxleName].DisplayRelativeZero
                    + rTS < 0)
                {
                    setState("运行目标超越绝对零位!");
                    return;
                }
                AxleCacheManager.AxleList[AxleName].Addtion = totalStep;
                Axle.Direction dirt = new Axle.Direction(direct);
                double pwm = AxleCacheManager.AxleList[AxleName].getRunPwm(m_runSpeed);
                bool setRst = AxleManager.ParameterSetting(AxleName
                    , new Axle.Direction(direct)
                    , AxleCacheManager.AxleList[AxleName].getRunPwm(m_runSpeed)
                    , AxleCacheManager.AxleList[AxleName].TotalStep
                    );
                AxleCacheManager.AxleList[AxleName].OnestepAddtion = direct == 0 ? totalStep : (0 - totalStep);
                if (setRst)
                {
                    setState(
                    string.Format("参数设置({0}|[{1}]|{2}|{3})成功"
                        , AxleName, dirt.ToString()
                        , pwm
                        , AxleCacheManager.AxleList[AxleName].TotalStep
                        )
                    );
                    AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                    bRst = AxleManager.Run(AxleName);
                }
                else
                {
                    setState(
                    string.Format("参数设置({0}|[{1}]|{2}|{3})失败"
                        , AxleName, dirt.ToString()
                        , pwm
                        , AxleCacheManager.AxleList[AxleName].TotalStep
                        )
                    );
                }
                //}//if int.tryparse totalstep

            }
            catch (Exception ex)
            {
                setState(
                                string.Format("参数设置错误:({0})"
                                    , ex.Message
                                    )
                                );
            }
            finally
            {
                if (bRst)
                {
                    setBtnState_AxleRunning();
                }
                btnDelayEnable(btnOneStepAddtion);
            }
        }
        
        /// <summary>
        /// 单步增量
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOneStepAddtion_Click(object sender, RoutedEventArgs e)
        {
            
        }

        #region bind
        /// <summary>
        /// 方向
        /// </summary>
        private static List<AddtionDirect> s_addDirectTypeList = new List<AddtionDirect>()
                {
                new AddtionDirect((int)Axle.Direction.ForwardDirection.Value,"+"),
                new AddtionDirect((int)Axle.Direction.BackDirection.Value,"-")
                };
        private static List<AccelerationSetting> s_accelerationList = new List<AccelerationSetting>()
        {
            new AccelerationSetting((int)Axle.AccelerationLevel.Constant,"匀速"),
            new AccelerationSetting((int)Axle.AccelerationLevel.GatherWay,"加速")
        };

        private static List<ToZeroSpeedSetting> s_tozeroSpeedList = new List<ToZeroSpeedSetting>()
        {
            new ToZeroSpeedSetting((int)Axle.ToZeroSpeed.Constant,"匀速"),
            new ToZeroSpeedSetting((int)Axle.ToZeroSpeed.GatherWay,"加速")
        };

        void accelerationBind(int value)
        {
            cmbAcceleration.ItemsSource = s_accelerationList;
            cmbAcceleration.DisplayMemberPath = "Name";
            cmbAcceleration.SelectedValuePath = "ID";
            if (value > 0)
            {
                cmbAcceleration.SelectedValue = value;
            }
            else
            {
                cmbAcceleration.SelectedIndex = 0;
            }
        }

        void tozeroSpeedBind()
        {
            //cmbTozeroSpeed.ItemsSource = s_tozeroSpeedList;
            //cmbTozeroSpeed.DisplayMemberPath = "Name";
            //cmbTozeroSpeed.SelectedValuePath = "ID";
            //cmbTozeroSpeed.SelectedIndex = 0;
        }

        void addtionDirectBind(int value)
        {
            //cmbAddtionDirect.ItemsSource = s_addDirectTypeList;
            //cmbAddtionDirect.DisplayMemberPath = "Name";
            //cmbAddtionDirect.SelectedValuePath = "ID";
            //if (value > 0)
            //{
            //    cmbAddtionDirect.SelectedValue = value;
            //}
            //else
            //{
            //    cmbAddtionDirect.SelectedIndex = 0;
            //}

            m_isForward = value == Axle.Direction.ForwardDirection.Value;
            //ImageBrush imageBrush = new ImageBrush();
            //Image img = new Image();
            ////System.Drawing.Bitmap img = null;
            ////System.Drawing.Icon img = null;
            //img.Width = 25;
            //img.Height = 25;
            if (m_isForward)
            {
                //imgAddDirect.Source = new BitmapImage(
                //    new Uri(
                //        "/KZ400B.Controls;component/Images/plus.png"
                //        , UriKind.Relative
                //        )
                //    );
                btnAddtionDirect.Content = "+";
            }
            else
            {
                //imgAddDirect.Source = new BitmapImage(
                //    new Uri(
                //        "/KZ400B.Controls;component/Images/minus.png"
                //        , UriKind.Relative
                //        )
                //    );
                btnAddtionDirect.Content = "-";
            }
            //if (img != null)
            //{
            //    btnAddtionDirect.Content = img;
            //}
        }

        void addtionBind(int value)
        {
            List<int> mList = new List<int>();
            for (int i = 1; i < 101; i++)
            {
                mList.Add(i);
            }

            cmbAddtion.ItemsSource = mList;
            if (value > 0)
            {
                cmbAddtion.SelectedItem = value;
            }
            else
            {
                cmbAddtion.SelectedIndex = 0;
            }
        }

        void targetBind(double target)
        {
            List<double> mList = new List<double>();
            for (int i = 1; i < 101; i++)
            {
                mList.Add((double)i);
            }

            cmbTarget.ItemsSource = mList;
            //if (target >= 0)
            { cmbTarget.BindValue(target); }
            //else
            //{
            //    cmbTarget.SelectedIndex = 0;
            //}
            
        }
        #endregion

        #region 变化事件
        //private void cmbAddtion_SelectionChanged(object sender, SelectionChangedEventArgs e)
        private void cmbAddtion_SelectionChanged(object sender)
        {
            int aValue = 0;
            //int bValue = 0;
            if (cmbAddtion.SelectedItem != null && int.TryParse(cmbAddtion.SelectedItem.ToString(), out aValue))
            {
                //if (cmbAddtionDirect.SelectedValue != null && int.TryParse(cmbAddtionDirect.SelectedValue.ToString(), out bValue))
                {
                    AxleCacheManager.AxleList[AxleName].OnestepAddtion = m_isForward ? aValue : 0 - aValue;
                    AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                    changeParam();
                }
            }
        }

        bool m_isForward = true;

        //public bool IsForward
        //{
        //    get { return m_isForward; }
        //}
        //private void cmbAddtionDirect_SelectionChanged(object sender, SelectionChangedEventArgs e)
        //{
        //    int aValue = 0;
        //    int bValue = 0;
        //    if (cmbAddtion.SelectedValue != null && int.TryParse(cmbAddtion.SelectedValue.ToString(), out aValue))
        //    {
        //        if (cmbAddtionDirect.SelectedValue != null && int.TryParse(cmbAddtionDirect.SelectedValue.ToString(), out bValue))
        //        {
        //            m_Axle.OnestepAddtion = bValue == 0 ? aValue : 0 - aValue;
        //            AxleCacheManager.Update(m_Axle);
        //            changeParam();
        //        }
        //    }
        //}


        private void cmbAcceleration_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!cx_check()) return;
            int aLevel = 0;
            if (cmbAcceleration.SelectedValue != null && int.TryParse(cmbAcceleration.SelectedValue.ToString(), out aLevel))
            {
                Axle.AccelerationLevel acc = new Axle.AccelerationLevel(aLevel);
                if (AxleManager.AccelerationSetting(AxleName, acc))
                {
                    setState(
                    string.Format("加速度({0}|[{1}])设置成功"
                        , AxleName, acc.ToString()
                        )
                    );
                    AxleCacheManager.AxleList[AxleName].RunAcceleration = aLevel;
                    AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                    changeParam();
                }
                else
                {
                    setState(
                    string.Format("加速度({0}|[{1}])设置失败"
                        , AxleName,acc.ToString()
                        )
                    );
                    cmbAcceleration.SelectedValue = AxleCacheManager.AxleList[AxleName].RunAcceleration;
                }
            }
        }

        private double m_runSpeed = 0.0F;

        public double RunSpeed
        {
            get { return m_runSpeed; }
        }
        private double m_tozeroSpeed = 0.0F;

        public double TozeroSpeed
        {
            get { return m_tozeroSpeed; }
        }
        private void txtTozeroSpeed_TextChanged(object sender, TextChangedEventArgs e)
        {
            double dValue = 0.0F;
            if (double.TryParse(txtTozeroSpeed.Text, out dValue))
            {
                if (AxleCacheManager.AxleList[AxleName].TozeroSpeed != dValue)
                {
                    AxleCacheManager.AxleList[AxleName].TozeroSpeed = dValue;
                    AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                    changeParam();
                }
            }
            m_tozeroSpeed = dValue;
        }

        private void txtSpeed_TextChanged(object sender, TextChangedEventArgs e)
        {
            double dValue = 0.0F;
            if (double.TryParse(txtSpeed.Text, out dValue))
            {
                if (AxleCacheManager.AxleList[AxleName].RunSpeed != dValue)
                {
                    AxleCacheManager.AxleList[AxleName].RunSpeed = dValue;
                    AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                    changeParam();
                }
            }
            m_runSpeed = dValue;
        }

        private void cmbTarget_DataChanged(object sender)
        {
            double dValue = 0;
            if (cmbTarget.SelectedItem != null && double.TryParse(cmbTarget.SelectedItem.ToString(), out dValue))
            {
                if (!AxleCacheManager.AxleList[AxleName].RunTarget.ToString(MySetting.PositionDisDeciFormatter).Equals(
                        dValue.ToString(MySetting.PositionDisDeciFormatter))
                    )
                {
                    AxleCacheManager.AxleList[AxleName].RunTarget = dValue;
                    AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                    changeParam();
                }
            }
        }

        #endregion

        //private bool m_paramChanged;
        private void resetPState()
        { 
        
        }
        /// <summary>
        /// 参数修改时调用
        /// </summary>
        private void changeParam()
        {
            //AxleManager.setParameterChanged(AxleName, true);
        //update to database
        }

        private void setRunning(bool running)
        { 
            
        }

        /// <summary>
        /// 判断电机是否正在运转
        /// </summary>
        /// <returns></returns>
        private bool isRunning()
        {
            return false;
        }

        /// <summary>
        /// 设置控件是否可用
        /// 如果正在运行应该设置其它控件为不可用
        /// 运行结束或者没有运行时为可用
        /// </summary>
        /// <param name="enable"></param>
        private void setEnable(bool enable)
        { 
            
        }



        public void setState(string state)
        {
            //if (OnStateChanged != null && !string.IsNullOrEmpty(state))
            //{
            //    OnStateChanged(null,state);
            //}
            KZ400B.Controls.StateMsgManager.addOneState(state);
        }

        private void btnAddtionDirect_Click(object sender, RoutedEventArgs e)
        {
            m_isForward = !m_isForward;
            addtionDirectBind(m_isForward ? Axle.Direction.ForwardDirection.Value : Axle.Direction.BackDirection.Value);
            int aValue = 0;
            if (cmbAddtion.SelectedItem != null && int.TryParse(cmbAddtion.SelectedItem.ToString(), out aValue))
            {
                AxleCacheManager.AxleList[AxleName].OnestepAddtion = m_isForward ? aValue : 0 - aValue;
                AxleCacheManager.Update(AxleCacheManager.AxleList[AxleName]);
                    changeParam();
                
            }
        }
        bool m_isOSRing = false;
        object m_isolk = null;
        public bool IsOneStepRunning
        {
            get { lock (m_isolk) { return m_isOSRing; } }
            set { lock (m_isolk) { m_isOSRing = value; } }
        }

        private void btnOneStepAddtion_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!cx_check()) return;
            double totalStep = 0;
            double runSpeed = 0.0F;
            if (!double.TryParse(cmbAddtion.SelectedItem.ToString(), out totalStep))
            {
                return;
            }
            else
            {
                m_osTotalStep = totalStep;
            }

            if (!double.TryParse(txtSpeed.Text, out runSpeed))
            {
                return;
            }
            else
            {
                m_osRunSpeed = runSpeed;
            }
            if (AxleRunState.Instance.CanRun(m_axleName))
            {
                IsOneStepRunning = true;
                AddOneStepAddtion();
            }
        }

        private void btnOneStepAddtion_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            IsOneStepRunning = false;
        }

        private void btnOneStepAddtion_LostFocus(object sender, RoutedEventArgs e)
        {
            IsOneStepRunning = false;
        }


    }
}
